home *** CD-ROM | disk | FTP | other *** search
- /* solar_irisgl.c
- * solar displays a planet with a moon orbiting a sun using
- * pure IRIG GL.
- *
- * Copyright 1991, Silicon Graphics, Inc. All Rights Reserved.
- * See ~/copyright for complete rights and liability information.
- * Author: Technical Education Course Developers
- */
-
- #include <gl/gl.h>
- #include <gl/device.h>
- #include <gl/get.h>
- #include <stdio.h>
- #include <math.h>
-
- /* function prototypes */
-
- void main( int, char ** );
- void initialize( char * );
- void drawscene(short angle);
- void setbeachball(int stripes);
- void beachball(unsigned long color1, unsigned long color2);
-
- /* main
- * main calls initialize, then goes into a loop. Within the loop
- * drawscene is called and passed an angle, the angle is
- * incremented and events in the event queue are processed
- * until user exits.
- *
- * The user can exit by pressing ESCAPE or through
- * the window manager.
- *
- * If the LEFTMOUSE button is pressed mouse x/y input is
- * read from the queue until the button is released.
- * The mouse x/y input is passed to drawscene.
- */
-
- void
- main( int argc, char *argv[] )
- {
- Boolean exitflag = FALSE;
- short value;
- long dev;
- short angle = 0;
- short attached = 0; /* attached flags changes to input focus */
-
- if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0) {
- fprintf(stderr, "This machine does not have a zbuffer\n");
- exit(0);
- }
- initialize( argv[0] );
-
- while (exitflag == FALSE) {
- drawscene(angle);
-
- /* increment angle each time scene is drawn */
- if (angle < 3600)
- angle = angle + 10;
- else
- angle = 0;
-
- while ( (exitflag == FALSE) && (qtest() || !attached) ) {
- /* if not attached, block until there is a
- * queue entry */
- dev = qread (&value);
- if (dev == ESCKEY) {
- /* if the device is ESCKEY, exit program
- * on key up */
- if (value == 0)
- exitflag = TRUE;
- }
- else if (dev == REDRAW) {
- /* if window needs to be redrawn,
- * tell the system that the shape
- * of the window may have changed,
- * then re-draw the scene */
- reshapeviewport();
- drawscene(angle);
- }
- else if (dev == INPUTCHANGE)
- attached = value;
- /* if cursor moves into window, value = gid
- * if cursor moves out of window, value = 0 */
- } /* end while exitflag FALSE and (qtest or not attached) */
- } /* end while exitflag FALSE */
- exit(0);
- } /* end main() */
-
- /* initialize
- * Positions the window and specifies its future constraints.
- * Graphics configuration is set and event queue is initialized.
- */
- void
- initialize( char *progname )
- {
- long gid1, xmax, ymax;
- float aspect;
-
- xmax = getgdesc(GD_XPMAX);
- ymax = getgdesc(GD_YPMAX);
-
- prefposition(xmax/4, xmax*3/4, ymax/4, ymax*3/4);
- gid1 = winopen( progname );
- minsize(xmax/10, ymax/10);
- keepaspect(xmax, ymax);
- winconstraints();
-
- doublebuffer();
- RGBmode();
- gconfig();
-
- zbuffer(TRUE);
- shademodel(FLAT);
-
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(ESCKEY);
- tie(LEFTMOUSE, MOUSEX, MOUSEY);
-
- /* separtae ModelView and Projection matrix stacks;
- * both are initialized with an identity matrix.
- */
- mmode(MVIEWING);
- aspect = (float) xmax / (float) ymax;
-
- /* projection commands replace projection matrix */
- perspective(450, aspect, 1.0, 25.0);
-
- /* viewing commands premultiply the ModelView matrix */
- polarview(12.0, 0, -100, 0);
- } /* end initialize() */
-
- /* drawscene
- * drawscene calculates angles relative to the yearangle,
- * and then draws sun, planet, and moon.
- */
-
- void
- drawscene(short yearangle)
- {
- static long blackcol[] = { 0, 0, 0 };
- static long bluecol[] = { 0, 0, 255 };
- static long whitecol[] = { 255, 255, 255 };
- short sunangle, dayangle, monthangle;
- /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
- float earthdist = 4.5, earthscale = 0.5;
- float moondist = 0.9, moonscale = 0.2;
-
- c3i(blackcol);
- /* clear color & z buffers */
- czclear(getgdesc(GD_ZMIN),getgdesc(GD_ZMAX));
- pushmatrix();
- sunangle = (yearangle*365/25) % 3600;
- /* sun rotates on axis every 25 days */
- rotate(sunangle, 'y');
- beachball(0x20C0FF, 0x200FFFF); /* colors in cpack format */
- popmatrix();
- pushmatrix();
- rotate(yearangle, 'y');
- translate(earthdist, 0.0, 0.0);
- pushmatrix();
- dayangle = (yearangle*50) % 3600; /* fudged so rotation shows */
- rotate(dayangle, 'y');
- scale(earthscale, earthscale, earthscale);
- c3i(bluecol);
- beachball(0xFF0000, 0xC02000); /* earth */
- popmatrix();
- monthangle = (yearangle*365/28) % 3600;
- rotate(monthangle, 'y');
- translate (moondist, 0.0, 0.0);
- scale(moonscale, moonscale, moonscale);
- c3i(whitecol);
- beachball(0xFFFFFF, 0xC0C0C0); /* moon */
- popmatrix();
-
- swapbuffers();
- } /* end drawscene() */
-
-
- /* BEACHBALL */
-
- /* three dimensional vector */
- typedef float vector[3];
-
- static vector front = { 0.0, 0.0, 1.0 };
- static vector back = { 0.0, 0.0, -1.0 };
- static vector top = { 0.0, 1.0, 0.0 };
- static vector bottom = { 0.0, -1.0, 0.0 };
- static vector right = { 1.0, 0.0, 0.0 };
- static vector left = { -1.0, 0.0, 0.0 };
- static vector center = { 0.0, 0.0, 0.0 };
-
- /* Number of colored stripes. Should be even to look right */
- #define BEACHBALL_STRIPES 12
-
- /* Default number of polygons making up a stripe. Should be even */
- #define BEACHBALL_POLYS 16
-
- /* array of vertices making up a stripe */
- static vector stripe_point[BEACHBALL_POLYS + 3];
-
- /* has the beachball been initialized */
- static Boolean beachball_initialized = FALSE;
-
- /* Number of polygons making up a stripe */
- static int beachball_stripes;
-
- /* Number of vertices making up a stripe */
- static int stripe_vertices;
-
- /* Initialize beachball_point array to be a stripe
- * of unit radius.
- */
- void setbeachball(int stripes)
- {
- int i,j;
- float x,y,z; /* vertex points */
- float theta,delta_theta; /* angle from top pole to bottom pole */
- float offset; /* offset from center of stripe to vertex */
- float cross_radius; /* radius of cross section at current latitude */
- float cross_theta; /* angle occupied by a stripe */
-
- beachball_stripes = stripes;
-
- /* polys distributed by even angles from top to bottom */
- delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
- theta = delta_theta;
-
- cross_theta = 2.0*M_PI/(float)beachball_stripes;
-
- j = 0;
-
- stripe_point[j][0] = top[0];
- stripe_point[j][1] = top[1];
- stripe_point[j][2] = top[2];
- j++;
-
- for (i = 0; i < BEACHBALL_POLYS; i += 2) {
- cross_radius = fsin(theta);
- offset = cross_radius * ftan(cross_theta/2.0);
-
- stripe_point[j][0] = - offset;
- stripe_point[j][1] = fcos(theta);
- stripe_point[j][2] = cross_radius;
- j++;
-
- stripe_point[j][0] = offset;
- stripe_point[j][1] = stripe_point[j-1][1];
- stripe_point[j][2] = stripe_point[j-1][2];
- j++;
-
- theta += delta_theta;
- }
-
- stripe_point[j][0] = bottom[0];
- stripe_point[j][1] = bottom[1];
- stripe_point[j][2] = bottom[2];
-
- stripe_vertices = j + 1;
-
- beachball_initialized = TRUE;
- }
-
- /*
- * Draws a canonical beachball. The colors are cpack values
- * when in RGBmode, colormap indices when in colormap mode.
- */
- void beachball(unsigned long c1, unsigned long c2)
- {
- long mode;
- float angle, delta_angle;
- int i,j;
-
- if (! beachball_initialized)
- setbeachball(BEACHBALL_STRIPES);
-
- mode = getdisplaymode();
-
- angle = 0.0;
- delta_angle = 360.0/(float)beachball_stripes;
-
- for (i = 0; i < beachball_stripes; i++) {
- switch(mode) {
- case DMSINGLE: case DMDOUBLE:
- if ( i%2 == 0)
- color(c1);
- else color(c2);
- break;
- case DMRGB: case DMRGBDOUBLE:
- if ( i%2 == 0)
- cpack(c1);
- else cpack(c2);
- break;
- }
-
- pushmatrix();
- rot(angle, 'y');
- angle += delta_angle;
-
- bgntmesh();
- for (j = 0; j < stripe_vertices; j++)
- v3f(stripe_point[j]);
- endtmesh();
- popmatrix();
- }
- }
-